package com.aspire.aimini.model.dto;

import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.experimental.Accessors;


import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 导出任务数据传输对象
 *
 * @author wangguiyou
 * @date 2024-12-19
 */
@Data
@Accessors(chain = true)
public class ExportTaskDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 任务ID
     */
    private String id;

    /**
     * 用户ID
     */
    @NotNull(message = "用户ID不能为空")
    private Long userId;

    /**
     * 数据类型
     */
    @NotBlank(message = "数据类型不能为空")
    private String dataType;

    /**
     * 导出格式
     */
    @NotBlank(message = "导出格式不能为空")
    private String format;

    /**
     * 任务状态
     */
    private String status;

    /**
     * 任务进度（0-100）
     */
    @Min(value = 0, message = "进度不能小于0")
    @Max(value = 100, message = "进度不能大于100")
    private Integer progress;

    /**
     * 过滤条件
     */
    private Map<String, Object> filters;

    /**
     * 导出选项
     */
    private Map<String, Object> options;

    /**
     * 文件路径
     */
    private String filePath;

    /**
     * 文件大小（字节）
     */
    private Long fileSize;

    /**
     * 下载URL
     */
    private String downloadUrl;

    /**
     * 错误信息
     */
    private String errorMessage;

    /**
     * 开始时间
     */
    private LocalDateTime startTime;

    /**
     * 完成时间
     */
    private LocalDateTime endTime;

    /**
     * 过期时间
     */
    private LocalDateTime expireTime;

    /**
     * 优先级（1-10）
     */
    @Min(value = 1, message = "优先级不能小于1")
    @Max(value = 10, message = "优先级不能大于10")
    private Integer priority;

    /**
     * 重试次数
     */
    private Integer retryCount;

    /**
     * 最大重试次数
     */
    private Integer maxRetryCount;

    /**
     * 处理的记录数量
     */
    private Long processedCount;

    /**
     * 总记录数量
     */
    private Long totalCount;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;

    /**
     * 可读的文件大小
     */
    private String readableFileSize;

    /**
     * 任务持续时间（毫秒）
     */
    private Long durationMillis;

    /**
     * 可读的持续时间
     */
    private String readableDuration;

    /**
     * 状态描述
     */
    private String statusDescription;

    /**
     * 数据类型描述
     */
    private String dataTypeDescription;

    /**
     * 格式描述
     */
    private String formatDescription;

    /**
     * 优先级描述
     */
    private String priorityDescription;

    /**
     * 是否可以下载
     */
    private Boolean canDownload;

    /**
     * 是否可以重试
     */
    private Boolean canRetry;

    /**
     * 是否可以取消
     */
    private Boolean canCancel;

    /**
     * 是否已过期
     */
    private Boolean isExpired;

    /**
     * 剩余有效时间（小时）
     */
    private Long remainingHours;

    /**
     * 估算完成时间
     */
    private LocalDateTime estimatedCompletionTime;

    /**
     * 处理速度（记录/秒）
     */
    private Double processingSpeed;

    /**
     * 获取状态描述
     */
    public String getStatusDescription() {
        if (status == null) {
            return "未知";
        }
        switch (status) {
            case "pending":
                return "等待中";
            case "processing":
                return "处理中";
            case "completed":
                return "已完成";
            case "failed":
                return "失败";
            case "cancelled":
                return "已取消";
            default:
                return "未知";
        }
    }

    /**
     * 获取数据类型描述
     */
    public String getDataTypeDescription() {
        if (dataType == null) {
            return "未知";
        }
        switch (dataType) {
            case "material":
                return "素材";
            case "copywriting":
                return "文案";
            case "tag":
                return "标签";
            case "statistics":
                return "统计数据";
            case "user_data":
                return "用户数据";
            default:
                return dataType;
        }
    }

    /**
     * 获取格式描述
     */
    public String getFormatDescription() {
        if (format == null) {
            return "未知";
        }
        switch (format.toLowerCase()) {
            case "json":
                return "JSON格式";
            case "csv":
                return "CSV格式";
            case "excel":
                return "Excel格式";
            case "pdf":
                return "PDF格式";
            default:
                return format.toUpperCase() + "格式";
        }
    }

    /**
     * 获取优先级描述
     */
    public String getPriorityDescription() {
        if (priority == null) {
            return "未设置";
        }
        if (priority >= 8) {
            return "高";
        }
        if (priority >= 5) {
            return "中";
        }
        return "低";
    }

    /**
     * 获取可读的文件大小
     */
    public String getReadableFileSize() {
        if (fileSize == null || fileSize < 0) {
            return "0 B";
        }

        String[] units = { "B", "KB", "MB", "GB", "TB" };
        int unitIndex = 0;
        double size = fileSize.doubleValue();

        while (size >= 1024 && unitIndex < units.length - 1) {
            size /= 1024;
            unitIndex++;
        }

        return String.format("%.2f %s", size, units[unitIndex]);
    }

    /**
     * 获取可读的持续时间
     */
    public String getReadableDuration() {
        if (durationMillis == null || durationMillis < 0) {
            return "0秒";
        }

        long seconds = durationMillis / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;

        if (hours > 0) {
            return String.format("%d小时%d分钟", hours, minutes % 60);
        }
        if (minutes > 0) {
            return String.format("%d分钟%d秒", minutes, seconds % 60);
        }
        return String.format("%d秒", seconds);
    }

    /**
     * 检查是否可以下载
     */
    public boolean canDownload() {
        return "completed".equals(status) && downloadUrl != null && !isExpired();
    }

    /**
     * 检查是否可以重试
     */
    public boolean canRetry() {
        return "failed".equals(status)
                && (retryCount == null || retryCount < (maxRetryCount != null ? maxRetryCount : 3));
    }

    /**
     * 检查是否可以取消
     */
    public boolean canCancel() {
        return "pending".equals(status) || "processing".equals(status);
    }

    /**
     * 检查是否已过期
     */
    public boolean isExpired() {
        return expireTime != null && LocalDateTime.now().isAfter(expireTime);
    }

    /**
     * 获取剩余有效时间（小时）
     */
    public long getRemainingHours() {
        if (expireTime == null) {
            return -1;
        }
        LocalDateTime now = LocalDateTime.now();
        if (now.isAfter(expireTime)) {
            return 0;
        }
        return java.time.Duration.between(now, expireTime).toHours();
    }

    /**
     * 计算处理速度（记录/秒）
     */
    public double calculateProcessingSpeed() {
        if (processedCount == null || processedCount <= 0 || durationMillis == null || durationMillis <= 0) {
            return 0.0;
        }
        return (double) processedCount / (durationMillis / 1000.0);
    }

    /**
     * 估算完成时间
     */
    public LocalDateTime estimateCompletionTime() {
        if (!"processing".equals(status) || totalCount == null || processedCount == null ||
                totalCount <= processedCount || durationMillis == null || durationMillis <= 0) {
            return null;
        }

        double speed = calculateProcessingSpeed();
        if (speed <= 0) {
            return null;
        }

        long remainingRecords = totalCount - processedCount;
        long remainingSeconds = (long) (remainingRecords / speed);

        return LocalDateTime.now().plusSeconds(remainingSeconds);
    }

    /**
     * 获取进度百分比文本
     */
    public String getProgressText() {
        if (progress == null) {
            return "0%";
        }
        return progress + "%";
    }

    /**
     * 获取处理进度文本
     */
    public String getProcessingProgressText() {
        if (processedCount == null || totalCount == null || totalCount <= 0) {
            return "0/0";
        }
        return processedCount + "/" + totalCount;
    }
}